package com.sam.im.heiqun.widgets.imagepicker;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ListPopupWindow;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.GridView;
import android.widget.Toast;

import com.sam.im.heiqun.R;
import com.sam.im.heiqun.utils.RxJavaUtil;
import com.sam.im.heiqun.widgets.imagepicker.intent.PhotoPreviewIntent;
import com.yuyh.library.nets.callbacks.AbsAPICallback;
import com.yuyh.library.nets.exceptions.ApiException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;

public class PhotoPickerActivity extends AppCompatActivity {

    public static final String TAG = PhotoPickerActivity.class.getName();

    private Context mCxt;

    /**
     * 图片选择模式，int类型
     */
    public static final String EXTRA_SELECT_MODE = "select_count_mode";
    /**
     * 单选
     */
    public static final int MODE_SINGLE = 0;
    /**
     * 多选
     */
    public static final int MODE_MULTI = 1;
    /**
     * 最大图片选择次数，int类型
     */
    public static final String EXTRA_SELECT_COUNT = "max_select_count";
    /**
     * 默认最大照片数量
     */
    public static final int DEFAULT_MAX_TOTAL = 9;
    /**
     * 是否显示相机，boolean类型
     */
    public static final String EXTRA_SHOW_CAMERA = "show_camera";
    /**
     * 是否显示可转发，boolean类型
     */
    public static final String EXTRA_SHOW_SEN_TO_OTHER = "show_send_to_other";
    /**
     * 默认选择的数据集
     */
    public static final String EXTRA_DEFAULT_SELECTED_LIST = "default_result";
    /** 筛选照片配置信息 */
    public static final String EXTRA_IMAGE_CONFIG = "image_config";
    /** 选择结果，返回为 ArrayList&lt;String&gt; 图片路径集合  */
    public static final String EXTRA_RESULT = "select_result";
    /**
     * 选择结果是否可转发
     */
    public static final String EXTRA_RESULT_CAN_SEND_TO_OTHER = "result_can_send_to_other";

    // 结果数据
    private ArrayList<String> resultList = new ArrayList<>();
    // 文件夹数据
    private ArrayList<Folder> mResultFolder = new ArrayList<>();

    private MenuItem menuDoneItem;
    private GridView mGridView;
    private View mPopupAnchorView;
    private Button btnAlbum;
    private Button btnPreview;
    private CheckBox cbCanSendToOther;

    // 最大照片数量
    private ImageCaptureManager captureManager;
    private int mDesireImageCount;
    private MediaConfig imageConfig; // 照片配置
    private boolean showSendToOther;

    private MediaGridAdapter mImageAdapter;
    private FolderAdapter mFolderAdapter;
    private ListPopupWindow mFolderPopupWindow;

    private boolean hasFolderGened = false;
    private boolean mIsShowCamera = false;

    private final String[] IMAGE_PROJECTION = {
            MediaStore.Images.Media.DATA,
            MediaStore.Images.Media.DISPLAY_NAME,
            MediaStore.Images.Media.DATE_ADDED,
            MediaStore.Images.Media._ID};

    private final String[] VIDEO_PROJECTION = {
            MediaStore.Video.Media.DATA,
            MediaStore.Video.Media.DISPLAY_NAME,
            MediaStore.Video.Media.DATE_ADDED,
            MediaStore.Video.Media.DURATION,
            MediaStore.Video.Media._ID};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photopicker);

        initViews();

        // 照片属性
        imageConfig = getIntent().getParcelableExtra(EXTRA_IMAGE_CONFIG);

        // 首次加载所有图片
        loadData(null);

        // 选择图片数量
        mDesireImageCount = getIntent().getIntExtra(EXTRA_SELECT_COUNT, DEFAULT_MAX_TOTAL);

        // 图片选择模式
        final int mode = getIntent().getExtras().getInt(EXTRA_SELECT_MODE, MODE_SINGLE);

        // 默认选择
        if (mode == MODE_MULTI) {
            ArrayList<String> tmp = getIntent().getStringArrayListExtra(EXTRA_DEFAULT_SELECTED_LIST);
            if (tmp != null && tmp.size() > 0) {
                resultList.addAll(tmp);
            }
        }

        //是否显示可转发
        showSendToOther = getIntent().getBooleanExtra(EXTRA_SHOW_SEN_TO_OTHER,false);

        // 是否显示照相机
        mIsShowCamera = getIntent().getBooleanExtra(EXTRA_SHOW_CAMERA, false);
        mImageAdapter = new MediaGridAdapter(mCxt, mIsShowCamera, getItemImageWidth());
        // 是否显示选择指示器
        mImageAdapter.showSelectIndicator(mode == MODE_MULTI);
        mGridView.setAdapter(mImageAdapter);

        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (mImageAdapter.isShowCamera()) {
                    // 如果显示照相机，则第一个Grid显示为照相机，处理特殊逻辑
                    if (i == 0) {
                        if (mode == MODE_MULTI) {
                            // 判断选择数量问题
                            if (mDesireImageCount == resultList.size()) {
                                Toast.makeText(mCxt, R.string.msg_amount_limit, Toast.LENGTH_SHORT).show();
                                return;
                            }
                        }
                        showCameraAction();
                    } else {
                        // 正常操作
                        MediaBean image = (MediaBean) adapterView.getAdapter().getItem(i);
                        selectImageFromGrid(image, mode);
                    }
                } else {
                    // 正常操作
                    MediaBean image = (MediaBean) adapterView.getAdapter().getItem(i);
                    selectImageFromGrid(image, mode);
                }
            }
        });

        mFolderAdapter = new FolderAdapter(mCxt);

        // 打开相册列表
        btnAlbum.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mFolderPopupWindow == null) {
                    createPopupFolderList();
                }

                if (mFolderPopupWindow.isShowing()) {
                    mFolderPopupWindow.dismiss();
                } else {
                    mFolderPopupWindow.show();
                    int index = mFolderAdapter.getSelectIndex();
                    index = index == 0 ? index : index - 1;
                    mFolderPopupWindow.getListView().setSelection(index);
                }
            }
        });

        // 预览
        btnPreview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PhotoPreviewIntent intent = new PhotoPreviewIntent(mCxt);
                intent.setCurrentItem(0);
                intent.setPhotoPaths(resultList);
                startActivityForResult(intent, PhotoPreviewActivity.REQUEST_PREVIEW);
            }
        });
        cbCanSendToOther.setVisibility(showSendToOther ? View.VISIBLE : View.GONE);
        cbCanSendToOther.setChecked(true);
    }

    private void initViews() {
        mCxt = this;
        captureManager = new ImageCaptureManager(mCxt);
        // ActionBar Setting
        Toolbar toolbar = (Toolbar) findViewById(R.id.pickerToolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle(getResources().getString(R.string.image_video));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mGridView = (GridView) findViewById(R.id.grid);
        mGridView.setNumColumns(getNumColnums());

        mPopupAnchorView = findViewById(R.id.photo_picker_footer);
        btnAlbum = (Button) findViewById(R.id.btnAlbum);
        btnPreview = (Button) findViewById(R.id.btnPreview);
        cbCanSendToOther = findViewById(R.id.cb_can_send_to_other);
    }

    private void createPopupFolderList() {

        mFolderPopupWindow = new ListPopupWindow(mCxt);
        mFolderPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mFolderPopupWindow.setAdapter(mFolderAdapter);
        mFolderPopupWindow.setContentWidth(ListPopupWindow.MATCH_PARENT);
        mFolderPopupWindow.setWidth(ListPopupWindow.MATCH_PARENT);

        // 计算ListPopupWindow内容的高度(忽略mPopupAnchorView.height)，R.layout.item_foloer
        int folderItemViewHeight =
                // 图片高度
                getResources().getDimensionPixelOffset(R.dimen.folder_cover_size) +
                        // Padding Top
                        getResources().getDimensionPixelOffset(R.dimen.folder_padding) +
                        // Padding Bottom
                        getResources().getDimensionPixelOffset(R.dimen.folder_padding);
        int folderViewHeight = mFolderAdapter.getCount() * folderItemViewHeight;

        int screenHeigh = getResources().getDisplayMetrics().heightPixels;
        if (folderViewHeight >= screenHeigh) {
            mFolderPopupWindow.setHeight(Math.round(screenHeigh * 0.6f));
        } else {
            mFolderPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);
        }

        mFolderPopupWindow.setAnchorView(mPopupAnchorView);
        mFolderPopupWindow.setModal(true);
        mFolderPopupWindow.setAnimationStyle(R.style.Animation_AppCompat_DropDownUp);
        mFolderPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                mFolderAdapter.setSelectIndex(position);

                final int index = position;
                final AdapterView v = parent;

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mFolderPopupWindow.dismiss();

                        if (index == 0) {
                            loadData(null);
                            btnAlbum.setText(R.string.all_image);
                            mImageAdapter.setShowCamera(mIsShowCamera);
                        } else {
                            Folder folder = (Folder) v.getAdapter().getItem(index);
                            if (null != folder) {
                                mImageAdapter.setData(folder.images);
                                btnAlbum.setText(folder.name);
                                // 设定默认选择
                                if (resultList != null && resultList.size() > 0) {
                                    mImageAdapter.setDefaultSelected(resultList);
                                }
                            }
                            mImageAdapter.setShowCamera(false);
                        }

                        // 滑动到最初始位置
                        mGridView.smoothScrollToPosition(0);
                    }
                }, 100);
            }
        });
    }

    public void onSingleImageSelected(String path) {
        Intent data = new Intent();
        resultList.add(path);
        data.putStringArrayListExtra(EXTRA_RESULT, resultList);
        data.putExtra(EXTRA_RESULT_CAN_SEND_TO_OTHER,cbCanSendToOther.isChecked());
        setResult(RESULT_OK, data);
        finish();
    }

    public void onImageSelected(String path) {
        if (!resultList.contains(path)) {
            resultList.add(path);
        }
        refreshActionStatus();
    }

    public void onImageUnselected(String path) {
        if (resultList.contains(path)) {
            resultList.remove(path);
        }
        refreshActionStatus();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                // 相机拍照完成后，返回图片路径
                case ImageCaptureManager.REQUEST_TAKE_PHOTO:
                    if (captureManager.getCurrentPhotoPath() != null) {
                        captureManager.galleryAddPic();
                        resultList.add(captureManager.getCurrentPhotoPath());
                    }
                    complete();
                    break;
                // 预览照片
                case PhotoPreviewActivity.REQUEST_PREVIEW:
                    ArrayList<String> pathArr = data.getStringArrayListExtra(PhotoPreviewActivity.EXTRA_RESULT);
                    // 刷新页面
                    if (pathArr != null && pathArr.size() != resultList.size()) {
                        resultList = pathArr;
                        refreshActionStatus();
                        mImageAdapter.setDefaultSelected(resultList);
                    }
                    break;
            }
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Log.d(TAG, "on change");

        // 重置列数
        mGridView.setNumColumns(getNumColnums());
        // 重置Item宽度
        mImageAdapter.setItemSize(getItemImageWidth());

        if (mFolderPopupWindow != null) {
            if (mFolderPopupWindow.isShowing()) {
                mFolderPopupWindow.dismiss();
            }

            // 重置PopupWindow高度
            int screenHeigh = getResources().getDisplayMetrics().heightPixels;
            mFolderPopupWindow.setHeight(Math.round(screenHeigh * 0.6f));
        }

        super.onConfigurationChanged(newConfig);
    }

    /**
     * 选择相机
     */
    private void showCameraAction() {
        try {
            Intent intent = captureManager.dispatchTakePictureIntent();
            startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO);
        } catch (IOException e) {
            Toast.makeText(mCxt, R.string.msg_no_camera, Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }

    /**
     * 选择图片操作
     *
     * @param image
     */
    private void selectImageFromGrid(MediaBean image, int mode) {
        if (image != null) {
            // 多选模式
            if (mode == MODE_MULTI) {
                if (resultList.contains(image.path)) {
                    resultList.remove(image.path);
                    onImageUnselected(image.path);
                } else {
                    // 判断选择数量问题
                    if (mDesireImageCount == resultList.size()) {
                        Toast.makeText(mCxt, R.string.msg_amount_limit, Toast.LENGTH_SHORT).show();
                        return;
                    }
                    resultList.add(image.path);
                    onImageSelected(image.path);
                }
                mImageAdapter.select(image);
            } else if (mode == MODE_SINGLE) {
                // 单选模式
                onSingleImageSelected(image.path);
            }
        }
    }

    /**
     * 刷新操作按钮状态
     */
    private void refreshActionStatus() {
        String text = getString(R.string.done_with_count, resultList.size(), mDesireImageCount);
        menuDoneItem.setTitle(text);
        boolean hasSelected = resultList.size() > 0;
        menuDoneItem.setVisible(hasSelected);
        btnPreview.setEnabled(hasSelected);
        if (hasSelected) {
            btnPreview.setText(getResources().getString(R.string.preview) + "(" + resultList.size() + ")");
        } else {
            btnPreview.setText(getResources().getString(R.string.preview));
        }
    }

    private void loadData(String pathLikes) {

        if (pathLikes == null) {
            pathLikes = "";
        }

        Observable.just(pathLikes)
                .flatMap(new Function<String, ObservableSource<List<MediaBean>>>() {
                    @Override
                    public ObservableSource<List<MediaBean>> apply(String pathLikes) throws Exception {

                        String selection = null;
                        String[] selectionArgs = null;

                        if (!TextUtils.isEmpty(pathLikes)) {
                            selection = IMAGE_PROJECTION[0] + " like '%?%'";
                            selectionArgs = new String[]{pathLikes};
                        }

                        Cursor cursor = null;

                        List<MediaBean> images = new ArrayList<>();

                        try {
                            cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                                    IMAGE_PROJECTION,
                                    buildSelectionArgs(),
                                    selectionArgs,
                                    IMAGE_PROJECTION[2] + " DESC");

                            if (cursor == null) {
                                return Observable.just(images);
                            }
                            while (cursor.moveToNext()) {

                                String path = cursor.getString(cursor.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
                                String name = cursor.getString(cursor.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
                                long dateTime = cursor.getLong(cursor.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));

                                MediaBean image = new MediaBean(path, name, dateTime, MediaBean.TYPE_IMAGE);
                                images.add(image);
                                if (!hasFolderGened) {
                                    // 获取文件夹名称
                                    File imageFile = new File(path);
                                    File folderFile = imageFile.getParentFile();
                                    Folder folder = new Folder();
                                    folder.name = folderFile.getName();
                                    folder.path = folderFile.getAbsolutePath();
                                    folder.cover = image;
                                    if (!mResultFolder.contains(folder)) {
                                        List<MediaBean> imageList = new ArrayList<>();
                                        imageList.add(image);
                                        folder.images = imageList;
                                        mResultFolder.add(folder);
                                    } else {
                                        // 更新
                                        Folder f = mResultFolder.get(mResultFolder.indexOf(folder));
                                        f.images.add(image);
                                    }
                                }
                            }

                            if(imageConfig == null || !imageConfig.loadVideos){
                                return Observable.just(images);
                            }

                            cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                                    VIDEO_PROJECTION,
                                    selection,
                                    selectionArgs,
                                    VIDEO_PROJECTION[2] + " DESC");

                            if (cursor == null) {
                                return Observable.just(images);
                            }
                            while (cursor.moveToNext()) {

                                String path = cursor.getString(cursor.getColumnIndexOrThrow(VIDEO_PROJECTION[0]));
                                String name = cursor.getString(cursor.getColumnIndexOrThrow(VIDEO_PROJECTION[1]));
                                long dateTime = cursor.getLong(cursor.getColumnIndexOrThrow(VIDEO_PROJECTION[2]));
                                long duration = cursor.getLong(cursor.getColumnIndexOrThrow(VIDEO_PROJECTION[3]));

                                MediaBean image = new MediaBean(path, name, dateTime, MediaBean.TYPE_VIDEO);
                                image.setVideoDuration(duration);
                                images.add(image);
                                if (!hasFolderGened) {
                                    // 获取文件夹名称
                                    File imageFile = new File(path);
                                    File folderFile = imageFile.getParentFile();
                                    Folder folder = new Folder();
                                    folder.name = folderFile.getName();
                                    folder.path = folderFile.getAbsolutePath();
                                    folder.cover = image;
                                    if (!mResultFolder.contains(folder)) {
                                        List<MediaBean> imageList = new ArrayList<>();
                                        imageList.add(image);
                                        folder.images = imageList;
                                        mResultFolder.add(folder);
                                    } else {
                                        // 更新
                                        Folder f = mResultFolder.get(mResultFolder.indexOf(folder));
                                        f.images.add(image);
                                    }
                                }
                            }
                            return Observable.just(images);
                        } finally {

                            if (cursor != null) {
                                cursor.close();
                            }
                        }
                    }
                })
                .map(new Function<List<MediaBean>, List<MediaBean>>() {
                    @Override
                    public List<MediaBean> apply(List<MediaBean> mediaBeans) throws Exception {
                        Collections.sort(mediaBeans, new Comparator<MediaBean>() {
                            @Override
                            public int compare(MediaBean o1, MediaBean o2) {
                                if (o1.time > o2.time) {
                                    return 1;
                                } else if (o1.time == o2.time) {
                                    return 0;
                                } else {
                                    return -1;
                                }
                            }
                        });

                        System.out.print(mediaBeans);
                        return mediaBeans;
                    }
                })
                .compose(RxJavaUtil.<List<MediaBean>>applySchedules())
                .subscribe(new AbsAPICallback<List<MediaBean>>() {
                    @Override
                    public void onNext(List<MediaBean> mediaBeans) {
                        //对相册照片进行倒序排序把最近的照片排到最前面
                        List<MediaBean> newList=new ArrayList();
                        if(mediaBeans!=null){
                            for (int i = mediaBeans.size()-1; i >0 ; i--) {
                                newList.add(mediaBeans.get(i));
                            }
                        }
                        mImageAdapter.setData(newList);
                        // 设定默认选择
                        if (resultList != null && resultList.size() > 0) {
                            mImageAdapter.setDefaultSelected(resultList);
                        }

                        mFolderAdapter.setData(mResultFolder);
                        hasFolderGened = true;
                    }

                    @Override
                    protected void onResultError(ApiException ex) {

                    }
                });
    }

    /**
     * 获取GridView Item宽度
     *
     * @return
     */
    private int getItemImageWidth() {
        int cols = getNumColnums();
        int screenWidth = getResources().getDisplayMetrics().widthPixels;
        int columnSpace = getResources().getDimensionPixelOffset(R.dimen.space_size);
        return (screenWidth - columnSpace * (cols - 1)) / cols;
    }

    /**
     * 根据屏幕宽度与密度计算GridView显示的列数， 最少为三列
     *
     * @return
     */
    private int getNumColnums() {
        int cols = getResources().getDisplayMetrics().widthPixels / getResources().getDisplayMetrics().densityDpi;
        return cols < 3 ? 3 : cols;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_picker, menu);
        menuDoneItem = menu.findItem(R.id.action_picker_done);
        menuDoneItem.setVisible(false);
        refreshActionStatus();
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }

        if (item.getItemId() == R.id.action_picker_done) {
            complete();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    // 返回已选择的图片数据
    private void complete() {
        Intent data = new Intent();
        data.putStringArrayListExtra(EXTRA_RESULT, resultList);
        data.putExtra(EXTRA_RESULT_CAN_SEND_TO_OTHER,cbCanSendToOther.isChecked());
        setResult(RESULT_OK, data);
        finish();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        captureManager.onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        captureManager.onRestoreInstanceState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }

    private String buildSelectionArgs(){

        // 根据图片设置参数新增验证条件
        StringBuilder selectionArgs = new StringBuilder();

        if(imageConfig != null){
            if(imageConfig.minWidth != 0){
                selectionArgs.append(MediaStore.Images.Media.WIDTH + " >= " + imageConfig.minWidth);
            }

            if(imageConfig.minHeight != 0){
                selectionArgs.append("".equals(selectionArgs.toString()) ? "" : " and ");
                selectionArgs.append(MediaStore.Images.Media.HEIGHT + " >= " + imageConfig.minHeight);
            }

            if(imageConfig.minSize != 0f){
                selectionArgs.append("".equals(selectionArgs.toString()) ? "" : " and ");
                selectionArgs.append(MediaStore.Images.Media.SIZE + " >= " + imageConfig.minSize);
            }

            if(imageConfig.mimeType != null){
                selectionArgs.append(" and (");
                for(int i = 0, len = imageConfig.mimeType.length; i < len; i++){
                    if(i != 0){
                        selectionArgs.append(" or ");
                    }
                    selectionArgs.append(MediaStore.Images.Media.MIME_TYPE + " = '" + imageConfig.mimeType[i] + "'");
                }
                selectionArgs.append(")");
            }
        }
        return selectionArgs.toString();
    }
}
